package com.yami.shop.platform.task;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.util.DataWebService;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.nft.common.model.NftApply;
import com.yami.shop.nft.common.model.NftApplyImg;
import com.yami.shop.nft.common.model.NftDaw;
import com.yami.shop.nft.common.model.NftDenom;
import com.yami.shop.nft.common.service.NftApplyImgService;
import com.yami.shop.nft.common.service.NftApplyService;
import com.yami.shop.nft.common.service.NftDawService;
import com.yami.shop.nft.common.service.NftDenomService;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MintsNftDawTask {
    @Autowired
    private DataWebService dataWebService;

    @Autowired
    private NftApplyService nftApplyService;

    @Autowired
    private ShopConfig shopConfig;

    @Autowired
    private NftDawService nftDawService;

    @Autowired
    private NftApplyImgService nftApplyImgService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private NftDenomService nftDenomService;
    @Autowired
    private SysConfigService sysConfigService;

    @XxlJob("activateCoinTask")
    public void activateCoin() {
        String DT_NFT_MINT_URL = shopConfig.getApiGatewayUrl() + "/nft/outapi/api/nftmint/mgsMintNft?";
        log.info("=======================================激活铸币进行消息推送的通知=========================================");
        // 查询申请成功 待铸币的的一条铸币信息
        LambdaQueryWrapper<NftDaw> nftDawLambdaQueryWrapper = new LambdaQueryWrapper<NftDaw>().eq(NftDaw::getChainUpStatus, 4).isNotNull(NftDaw::getDawId).orderByAsc(NftDaw::getDenomId,NftDaw::getNftCode).last("limit 200");
        List<NftDaw> list = nftDawService.list(nftDawLambdaQueryWrapper);
        if(list.isEmpty()){
            log.info("暂无激活铸币上链数据================================================");
            return;
        }
        if(!RedisUtil.hasKey("activateCoinTask")){
            log.info("激活铸币*************");
            RedisUtil.set("taskCheckAllNftData","true",0);
        }else{
            log.info("正在激活铸币上链数据================================================");
            return;
        }
        Map<String, List<NftDaw>> collect = list.stream().collect(Collectors.groupingBy(NftDaw::getDenomId));
        for (String denomId:  collect.keySet()){
            List<NftDaw> nftDaws = collect.get(denomId);
            LambdaQueryWrapper<NftApply> last = new LambdaQueryWrapper<NftApply>().eq(NftApply::getDenomId, denomId).eq(NftApply::getMintType, 0).eq(NftApply::getApplyStatus, 2).eq(NftApply::getMintStatus, 2).last("limit 1");
            NftApply one = nftApplyService.getOne(last);
            LambdaQueryWrapper<NftApplyImg> nftApplyImgLambdaQueryWrapper = new LambdaQueryWrapper<NftApplyImg>().eq(NftApplyImg::getApplyId, one.getId());
            // 获取铸币账号
            NftApplyImg nftApplyImg = nftApplyImgService.getOne(nftApplyImgLambdaQueryWrapper);
            ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(one.getShopId());
            Map<String, Object> param = new HashMap<>();
            List<String> nftIds = new ArrayList<>();
            List<String> operationIdList = new ArrayList<>();
            String energy = String.valueOf(nftIds.size() * 3);
            for (NftDaw nftDaw : nftDaws) {
                nftIds.add(nftDaw.getDawId());
            }
            param.put("energy", energy);
            param.put("chain", "dt");
            param.put("operationIds", operationIdList);
            param.put("nftIds", nftIds);
            param.put("data", "[do-not-modify]");
            param.put("denomId", denomId);
            param.put("dawName", one.getNftName());
            // 源文件获取
            JSONObject imgJson = JSONObject.parseObject(nftApplyImg.getImgUrl());
            param.put("dawUri", imgJson.getString("sourceFile"));
            try {
                NftDaw nftDaw = new NftDaw();
                LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
                nftDaw.setChainUpStatus(2);
                nftDawService.update(nftDaw, in);
//                JSONObject jsonObject = dataWebService.hutoolPostObjWebService(DT_NFT_MINT_URL, param, shopDetailByShopId.getApiUser(), shopDetailByShopId.getApiPassword());
//                if (jsonObject.getInteger("code") == Constant.SUCCESS_CODE) {
//                    // 成功
//                    NftDaw nftDaw = new NftDaw();
//                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
//                    nftDaw.setChainUpStatus(2);
//                    nftDawService.update(nftDaw, in);
//                } else {
//                    // 失败
//                    NftDaw nftDaw = new NftDaw();
//                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
//                    nftDaw.setChainUpStatus(5);
//                    nftDawService.update(nftDaw, in);
//                    NftApply updateApply = new NftApply();
//                    updateApply.setId(one.getId());
//                    updateApply.setMintErrorLog(jsonObject.getString("msg"));
//                    nftApplyService.updateById(updateApply);
//                }
            } catch (Exception e) {
                log.info("铸币异常", e);
                // 失败
                NftDaw nftDaw = new NftDaw();
                LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
                nftDaw.setChainUpStatus(5);
                nftDawService.update(nftDaw, in);
                NftApply updateApply = new NftApply();
                updateApply.setId(one.getId());
                updateApply.setMintErrorLog(e.getMessage());
                nftApplyService.updateById(updateApply);
            }
        }
        RedisUtil.del("taskCheckAllNftData");
    }
    @XxlJob("mintNftTask")
    public void mintNftTask() {
        String DT_NFT_MINT_URL = shopConfig.getApiGatewayUrl() + "/nft/outapi/api/nftmint/mgsMintNft?";
//        String DT_NFT_MINT_URL = "192.168.1.127:9209/outapi/api/nftmint/mgsMintNft?";
        log.info("=======================================铸币进行消息推送的通知=========================================");
        // 查询申请成功 待铸币的的一条铸币信息
        LambdaQueryWrapper<NftApply> last = new LambdaQueryWrapper<NftApply>().eq(NftApply::getApplyStatus, 2).eq(NftApply::getMintStatus, 1).orderByAsc(NftApply::getCreateTime).last("limit 1");
        NftApply one = nftApplyService.getOne(last);
        if (ObjectUtils.isEmpty(one)) {
            log.info("暂无审核上链数据================================================");
            return;
        }
        LambdaQueryWrapper<NftDenom> eq = new LambdaQueryWrapper<NftDenom>().eq(NftDenom::getDenomId, one.getDenomId());
        NftDenom nftDenom = nftDenomService.getOne(eq);
        // 查询前200条 上链
        LambdaQueryWrapper<NftDaw> nftDawLambdaQueryWrapper = new LambdaQueryWrapper<NftDaw>().eq(NftDaw::getChainUpStatus, 0).eq(NftDaw::getDenomId, one.getDenomId()).orderByAsc(NftDaw::getCreateTime,NftDaw::getNftCode).last("limit 200");
        List<NftDaw> list = nftDawService.list(nftDawLambdaQueryWrapper);
        if (ObjectUtils.isEmpty(list)) {
            NftApply successApply = new NftApply();
            successApply.setId(one.getId());
            log.info("暂无上链数据================================================");
            if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
                successApply.setMintStatus(4);
            } else {
                successApply.setMintStatus(2);
            }
            // 修改铸币状态
            nftApplyService.updateById(successApply);
            return;
        }

        // 追加铸币 获取源文件
        LambdaQueryWrapper<NftApplyImg> nftApplyImgLambdaQueryWrapper;
        if (one.getMintType() == 0) {
            nftApplyImgLambdaQueryWrapper = new LambdaQueryWrapper<NftApplyImg>().eq(NftApplyImg::getApplyId, one.getId());
        } else {
            nftApplyImgLambdaQueryWrapper = new LambdaQueryWrapper<NftApplyImg>().eq(NftApplyImg::getApplyId, one.getParentId());
        }
        // 获取铸币账号
        NftApplyImg nftApplyImg = nftApplyImgService.getOne(nftApplyImgLambdaQueryWrapper);
        ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(one.getShopId());
        Map<String, Object> param = new HashMap<>();
        List<String> nftIds = new ArrayList<>();
        List<String> operationIdList = new ArrayList<>();
        String energy = "1";
        if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
            for (NftDaw nftDaw : list) {
                operationIdList.add(nftDaw.getOperationId());
            }
            energy = String.valueOf(operationIdList.size() * 3);
        }else{
            for (NftDaw nftDaw : list) {
                nftIds.add(nftDaw.getDawId());
            }
            energy = String.valueOf(nftIds.size() * 3);
        }
        param.put("denomId", one.getDenomId());
        param.put("dawName", one.getNftName());
        // 源文件获取
        JSONObject imgJson = JSONObject.parseObject(nftApplyImg.getImgUrl());
        String minio_oss_config = sysConfigService.getValue("MINIO_OSS_CONFIG");
        JSONObject minioJson = JSONObject.parseObject(minio_oss_config);
        if(nftDenom.getBlockchainCode().equals("dt")){
            param.put("dawUri", imgJson.getString("sourceFile"));
        }else{
            param.put("dawUri", minioJson.getString("endpoint") + "/" + imgJson.getString("sourceFile"));
        }
        param.put("energy", energy);
        param.put("chain", nftDenom.getBlockchainCode());
        param.put("recipient", nftDenom.getOwner());
        param.put("operationIds", operationIdList);
        if(nftDenom.getBlockchainCode().equals("hw")){
            param.put("statrtNftId", list.get(0).getDawId());
            param.put("amount", String.valueOf(nftIds.size()));
            param.put("description", one.getNftName());
        }else{
            param.put("nftIds", nftIds);
            param.put("data", "[do-not-modify]");
        }
        try {
//            JSONObject jsonObject = dataWebService.hutoolPostObjWebService(DT_NFT_MINT_URL, param, shopDetailByShopId.getApiUser(), shopDetailByShopId.getApiPassword());
//            if (jsonObject.getInteger("code") == Constant.SUCCESS_CODE) {
                // 成功
                NftDaw nftDaw = new NftDaw();
                if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getOperationId,operationIdList);
                    nftDaw.setChainUpStatus(4);
                    nftDawService.update(nftDaw, in);
                } else {
                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
                    nftDaw.setChainUpStatus(2);
                    nftDawService.update(nftDaw, in);
                }

                // 不足200 最后一批修改完成状态
                if (nftIds.size() < 200) {
                    NftApply successApply = new NftApply();
                    successApply.setId(one.getId());
                    if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
                        successApply.setMintStatus(4);
                    } else {
                        successApply.setMintStatus(2);
                    }
                    // 修改铸币状态
                    nftApplyService.updateById(successApply);
                }
//            } else {
//                // 失败
//                NftDaw nftDaw = new NftDaw();
//                if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
//                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getOperationId,operationIdList);
//                    nftDaw.setChainUpStatus(1);
//                    nftDawService.update(nftDaw, in);
//                } else {
//                    LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
//                    nftDaw.setChainUpStatus(1);
//                    nftDawService.update(nftDaw, in);
//                }
//                NftApply updateApply = new NftApply();
//                updateApply.setId(one.getId());
//                updateApply.setMintStatus(3);
//                updateApply.setMintErrorLog(jsonObject.getString("msg"));
//                nftApplyService.updateById(updateApply);
//            }
        } catch (Exception e) {
            log.info("铸币异常", e);
            // 失败
            NftDaw nftDaw = new NftDaw();
            if (nftDenom.getBlockchainCode().equals("avata") || nftDenom.getBlockchainCode().equals("szavata")) {
                LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getOperationId,operationIdList);
                nftDaw.setChainUpStatus(1);
                nftDawService.update(nftDaw, in);
            } else {
                LambdaUpdateWrapper<NftDaw> in = new LambdaUpdateWrapper<NftDaw>().in(NftDaw::getDawId, nftIds);
                nftDaw.setChainUpStatus(1);
                nftDawService.update(nftDaw, in);
            }
            NftApply updateApply = new NftApply();
            updateApply.setId(one.getId());
            updateApply.setMintStatus(3);
            updateApply.setMintErrorLog(e.getMessage());
            nftApplyService.updateById(updateApply);
        }

    }

    @XxlJob("txNftTask")
    public void txNftTask() {
        String NFT_TL_URL = shopConfig.getApiGatewayUrl() + "/nft/outapi/api/nftmint/tx?";
//        String NFT_TL_URL = "192.168.1.127:9209/outapi/api/nftmint/tx?";
        log.info("=======================================文昌链查询交易=========================================");
        // 查询前200条 文昌链api上链查询交易状态
        LambdaQueryWrapper<NftApply> last = new LambdaQueryWrapper<NftApply>().eq(NftApply::getApplyStatus, 2).eq(NftApply::getMintStatus, 4).orderByAsc(NftApply::getCreateTime).last("limit 1");
        NftApply nftApply = nftApplyService.getOne(last);
        if (ObjectUtils.isEmpty(nftApply)) {
            log.info("暂无上链查询交易信息================================================");
            return;
        }
        LambdaQueryWrapper<NftDaw> nftDawLambdaQueryWrapper = new LambdaQueryWrapper<NftDaw>().eq(NftDaw::getChainUpStatus, 4).eq(NftDaw::getDenomId, nftApply.getDenomId()).orderByAsc(NftDaw::getCreateTime).last("limit 200");
        List<NftDaw> list = nftDawService.list(nftDawLambdaQueryWrapper);
        if (ObjectUtils.isEmpty(list)) {
            log.info("暂无上链查询交易信息数据================================================");
            NftApply successApply = new NftApply();
            successApply.setId(nftApply.getId());
            // 修改铸币状态  0待铸币 1 铸币中 2铸币成功 3铸币失败
            successApply.setMintStatus(2);
            nftApplyService.updateById(successApply);
            return;
        }
        ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(nftApply.getShopId());
        for (NftDaw nftDaw : list) {
            Map<String, String> param = new HashMap<>();
            param.put("operationId", nftDaw.getOperationId());
            param.put("chainCode",nftDaw.getBlockchainCode());
            try {
                JSONObject jsonObject = dataWebService.hutoolGetWebService(NFT_TL_URL, param, shopDetailByShopId.getApiUser(), shopDetailByShopId.getApiPassword());
                if (jsonObject.getInteger("code") == Constant.SUCCESS_CODE) {
                    JSONObject data1 = jsonObject.getJSONObject("data");
                    JSONObject data = data1.getJSONObject("data");
                    JSONObject nft = data.getJSONObject("nft");
                    String status = data.getString("status");
                    // status 为 0（处理中），上链请求正在处理，请等待处理完成；
                    //status 为 1（成功），交易已上链并执行成功；
                    //status 为 2（失败），说明该交易执行失败。请在业务侧做容错处理。
                    //status 为 3（未处理），上链请求还在等待处理，请稍等
                    // 成功
                    if (status.equals("1")) {
                        nftDaw.setChainUpStatus(2);
                        if(nftDaw.getBlockchainCode().equals("avata")){
                            nftDaw.setDawId(nft.getString("id"));
                            nftDaw.setNftCode(String.format("%05d", Integer.valueOf(nft.getString("id"))));
                        }else{
                            nftDaw.setDawId(nft.getString("nft_id"));
                        }
                        nftDawService.updateById(nftDaw);
                    }
                }
            } catch (Exception e) {
                log.info("查询上链类别交易信息异常", e);
            }

        }

    }

    @XxlJob("txDenomNftTask")
    public void txDenomNftTask() {
        String NFT_TXCLASS_URL = shopConfig.getApiGatewayUrl() + "/nft/outapi/api/nftmint/txclass?";
//        String NFT_TXCLASS_URL = "192.168.1.127:9209/outapi/api/nftmint/txclass?";
        log.info("-----------------------------文昌链查询类别交易----------------------------------");
        LambdaQueryWrapper<NftDenom> avata = new LambdaQueryWrapper<NftDenom>().isNull(NftDenom::getDenomId).orderByAsc(NftDenom::getCreateTime).last("limit 100");
        List<NftDenom> list = nftDenomService.list(avata);
        if (ObjectUtils.isEmpty(list)) {
            log.info("暂无上链类别交易信息================================================");
            return;
        }
        for (NftDenom nftDenom : list) {
            ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(Long.valueOf(nftDenom.getShopId()));
            Map<String, String> param = new HashMap<>();
            param.put("operationId", nftDenom.getOperationId());
            param.put("chainCode",nftDenom.getBlockchainCode());
            try {
                JSONObject jsonObject = dataWebService.hutoolGetWebService(NFT_TXCLASS_URL, param, shopDetailByShopId.getApiUser(), shopDetailByShopId.getApiPassword());

                if (jsonObject.getInteger("code") == Constant.SUCCESS_CODE) {
                    JSONObject data1 = jsonObject.getJSONObject("data");
                    JSONObject data = data1.getJSONObject("data");
                    JSONObject nft = data.getJSONObject("nft");
                    String status = data.getString("status");
                    // status 为 0（处理中），上链请求正在处理，请等待处理完成；
                    //status 为 1（成功），交易已上链并执行成功；
                    //status 为 2（失败），说明该交易执行失败。请在业务侧做容错处理。
                    //status 为 3（未处理），上链请求还在等待处理，请稍等
                    // 成功
                    if (status.equals("1")) {
                        nftDenom.setDenomId(nft.getString("class_id"));
                        nftDenomService.updateById(nftDenom);
                    }
                }
            } catch (Exception e) {
                log.info("查询上链类别交易信息异常", e);
            }
        }
    }
}

